package com.sec.android.app.myfiles.fragment;

import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.sec.android.app.myfiles.BuildConfig;
import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.activity.FileListActivity;
import com.sec.android.app.myfiles.activity.FolderSelectorBottomSheetActivity;
import com.sec.android.app.myfiles.activity.GetMoreSpaceActivity;
import com.sec.android.app.myfiles.app.MyFilesApplication;
import com.sec.android.app.myfiles.feature.SmartTipMgr;
import com.sec.android.app.myfiles.feature.ViEffectMgr;
import com.sec.android.app.myfiles.fragment.filelist.FileListActionMenu;
import com.sec.android.app.myfiles.fragment.filelist.PathIndicator;
import com.sec.android.app.myfiles.info.AppConstants;
import com.sec.android.app.myfiles.info.AppFeatures;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.log.Log.SluggishType;
import com.sec.android.app.myfiles.module.ContentObservable;
import com.sec.android.app.myfiles.module.abstraction.AbsContentObserverImp;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.shortcut.ShortcutFileRecord;
import com.sec.android.app.myfiles.navigation.NavigationInfo;
import com.sec.android.app.myfiles.provider.PrivateMyFilesProvider;
import com.sec.android.app.myfiles.util.PreferenceUtils;
import com.sec.android.app.myfiles.util.SmartTipUtils;
import com.sec.android.app.myfiles.util.UiUtils;
import com.squareup.leakcanary.RefWatcher;

import java.util.ArrayList;

public abstract class AbsMyFilesFragment extends Fragment implements Callback, ContentObservable {
    protected Context mContext;
    protected NavigationInfo mNavigationInfo;
    protected FileListActionMenu mMenu;
    protected FileListActivity mActivity;
    private ActionMode mActionMode;
    protected ActionModeType mActionModeType;
    public int mProcessId;
    private ActionModeChangeListener mActionModeListener;
    protected boolean mIsNeedRefreshViewAs = false;
    private boolean mIsDragStarted = false;

    private static final long sContentUpdateTime = 1000;
    private volatile Handler mContentUpdateHandler = null;
    private int mEvent;

    private int mTouchPos;
    private int mPanelInfo = 0;
    protected View mView;

    public abstract void reload();

    public abstract ArrayList<FileRecord> getSelectedFile();

    public abstract int getSelectedFileCount();

    public abstract int getTotalFileCount();

    public abstract int getTotalCheckableFileCount();

    public abstract FileRecord getFileRecord(int position);

    public abstract void selectAll(boolean select);

    public abstract void setEmptyView();

    public abstract void clearEmptyView();

    public abstract void onLoadFinished();

    public abstract void setLoadingView();

    public abstract AbsListView getListView();

    public void setDeleteItemEffect() {
    }

    public enum ActionModeType {
        NORMAL,
        SELECT_FILE_FOLDER_OPERATION,
        SELECT_SHARE_FILE_OPERATION,
        EDIT_FILE_FOLDER_OPERATION
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mContext = context;
        mActivity = (FileListActivity) getActivity();
        attachMenu();
    }

    @Override
    public void onDetach() {
        mNavigationInfo = null;

        if (mActionMode != null) {
            finishActionMode();
        }
        super.onDetach();
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.sluggish(SluggishType.Execute);
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    public void setNavigationInfo(NavigationInfo navigationInfo) {
        mNavigationInfo = navigationInfo;
    }

    public NavigationInfo getNavigationInfo() {
        return mNavigationInfo;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        boolean handled = false;
        if (mMenu != null) {
            handled = mMenu.onActivityResult(requestCode, resultCode, data);
        }

        if (!handled) {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    public void setProcessId(int processId) {
        mProcessId = processId;
    }

    public int getProcessId() {
        return mProcessId;
    }

    public void setActionMode(ActionModeType actionMode) {
        Log.d(this, "setActionMode(): " + actionMode);
        mActionModeType = actionMode;

        if (mActivity != null) {
            mMenu = mActivity.getActionMenu();
            mActionMode = mMenu.setActionBar(mActivity, mActionModeType, this);

            if (mActionModeListener != null) {
                mActionModeListener.onActionModeChanged(mNavigationInfo == null ? null : mNavigationInfo.getNavigationMode(), actionMode);
            }
        }
    }

    public ActionModeType getActionModeType() {
        return mActionModeType;
    }

    public void setActionModeType(ActionModeType actionModeType) {
        mActionModeType = actionModeType;
    }

    public int getListItemCount() {
        return 0;
    }

    public int getRecentItemCount() {
        return 0;
    }

    /**
     * Finish action(select file/folder) mode
     * <p/>
     * notice : selected items are cleared
     */
    public void finishActionMode() {
        if (mActionMode != null) {
            mActionMode.finish();
            mActionMode = null;
        }
    }

    public boolean isSelectActionMode() {
        boolean bRet = false;
        if (mActionModeType == ActionModeType.SELECT_FILE_FOLDER_OPERATION || mActionModeType == ActionModeType.EDIT_FILE_FOLDER_OPERATION
                || mActionModeType == ActionModeType.SELECT_SHARE_FILE_OPERATION) {
            bRet = true;
        }
        return bRet;
    }

    public void setNeedRefreshViewAs(boolean bValue) {
        mIsNeedRefreshViewAs = bValue;
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        if (mMenu != null) {
            mMenu.onCreateOptionsMenu(mode, menu, mode.getMenuInflater(), mActionModeType);
            mMenu.onPrepareActionMenu(menu, mActionModeType);
        }

        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        Log.a(this, "onDestroyActionMode()");

        setActionMode(ActionModeType.NORMAL);
        if (mActivity != null) {
            mActivity.invalidateOptionsMenu();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        RefWatcher refWatcher = MyFilesApplication.getRefWatcher(getActivity());
        if (BuildConfig.DEBUG && refWatcher != null) {
            refWatcher.watch(this);
        }
        mContext = null;
        mActivity = null;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        boolean bRet = false;
        if (mMenu != null) {
            bRet = mMenu.onOptionsItemSelected(item);
        }

        return bRet;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    public void updateActionBarMenu() {
        if (mMenu != null) {
            if (mActionMode != null) {
                Menu actionModeMenu = mActionMode.getMenu();
                if (actionModeMenu != null) {
                    mMenu.onPrepareActionMenu(actionModeMenu, mActionModeType);
                }
            } else {
                mMenu.updateSelectedItemView();
            }
        }
    }

    public Context context() {
        return mContext;
    }

    /**
     * <pre>
     * When content is changed update sContentUpdateTime later
     * if content is changed within sContentUpdateTime, update is delayed.
     * </pre>
     */
    @Override
    public final void onContentChanged(final FileRecord record, int event) {
        boolean bCreated = false;
        if (mContentUpdateHandler == null) {
            synchronized (this) {
                if (mContentUpdateHandler == null) {
                    mContentUpdateHandler = new Handler();
                    bCreated = true;
                    Log.d(this, "onContentChanged create new handler");
                }
            }
        }

        if (!bCreated) {
            mContentUpdateHandler.removeCallbacks(mContentChangedRunnable);
        }

        mEvent = event;
        mContentUpdateHandler.postDelayed(mContentChangedRunnable, sContentUpdateTime);
    }

    private Runnable mContentChangedRunnable = new Runnable() {
        @Override
        public void run() {
            Log.d(this, "mContentChangedRunnable run...");
            _onContentChanged(mEvent);
            mContentUpdateHandler = null;
            PrivateMyFilesProvider.refreshDb(mContext, new ShortcutFileRecord());
        }
    };

    protected abstract void _onContentChanged(int event);

    public boolean hasSubTitle() {
        boolean bRet = false;
        if (mNavigationInfo != null && mNavigationInfo.isPickerMode()) {
            if (mNavigationInfo.getExtensionFilter() != null || mNavigationInfo.getMimeTypeFilter() != null || mNavigationInfo.getCategoryFilter() != null) {
                bRet = true;
            }
        }
        return bRet;
    }

    public boolean getLoadingStatus() {
        return false;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Context context = mActivity.getBaseContext();
        context.setTheme(R.style.MyFiles_Default);

        setPathIndicator((PathIndicator) mActivity.findViewById(R.id.path_indicator));
        setPathIndicatorDivider((ImageView) mActivity.findViewById(R.id.path_indicator_divider));
    }

    public void setPathIndicator(PathIndicator pathIndicator) {
        if (pathIndicator != null) {
            pathIndicator.setFragment(this);
            pathIndicator.setVisibility(View.GONE);
        }
    }

    public void setPathIndicatorDivider(ImageView pathIndicatorDivider) {
        if (pathIndicatorDivider != null) {
            pathIndicatorDivider.setVisibility(View.VISIBLE);
        }
    }

    public void setActionModeChangeListener(ActionModeChangeListener listener) {
        mActionModeListener = listener;
    }

    public interface ActionModeChangeListener {
        void onActionModeChanged(NavigationInfo.NavigationMode naviMode, ActionModeType actionModeType);
    }

    public void startObserver() {
        Log.d(this, "startObserver");
        if (mNavigationInfo != null) {
            for (int i = 0; i < mNavigationInfo.getObserverSize(); i++) {
                AbsContentObserverImp observerImp = mNavigationInfo.getContentObserver(i);
                if (observerImp != null) {
                    observerImp.start();
                }
            }
        }

    }

    public void stopObserver() {
        Log.d(this, "stopObserver");
        if (mNavigationInfo != null) {
            for (int i = 0; i < mNavigationInfo.getObserverSize(); i++) {
                AbsContentObserverImp observerImp = mNavigationInfo.getContentObserver(i);
                if (observerImp != null) {
                    observerImp.stop();
                }
            }
        }
    }

    public void onConfigurationChanged(Configuration newConfig) {
        if (mActivity != null) {
            boolean isDensityChanged = UiUtils.isDensityDpiChanged(newConfig, mActivity.getDensityDpi());
            if (isDensityChanged) {
                finishActionMode();
                UiUtils.replaceFragment(this);
            }
        }
    }

    public void clearObserver() {
        stopObserver();
        if (mNavigationInfo != null) {
            mNavigationInfo.clearObserver();
        }
    }

    public void setDragStarted(boolean isDragStarted) {
        mIsDragStarted = isDragStarted;
    }

    public boolean isDragtStarted() {
        return mIsDragStarted;
    }

    protected void closePopupDialog() {
        UiUtils.sendLocalBroadcastIntent(mContext, AppConstants.DISMISS_DIALOG, getProcessId());
    }

    public void clearListViewPreValue() {
    }

    public FileRecord.StorageType getStorageType() {
        FileRecord.StorageType ret = FileRecord.StorageType.None;
        if (mNavigationInfo != null) {
            ret = mNavigationInfo.getStorageType();
        }
        return ret;
    }

    public void showMaxSelectedFilesToast() {
        String msg = mContext.getResources().getString(R.string.max_num_selected_files, mNavigationInfo.getMaxSelectCnt());
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }

    protected void attachMenu() {
        if (mActivity != null && mMenu == null) {
            mMenu = mActivity.getActionMenu();
        }
        mMenu.setInfo(this, mNavigationInfo);
    }

    public FileListActivity getFileListActivity() {
        return mActivity;
    }

    public void setTouchPosition(int pos) {
        mTouchPos = pos;
    }

    public int getTouchPosition() {
        return mTouchPos;
    }

    public int getPanelInfo() {
        return mPanelInfo;
    }

    public void setPanelInfo(int info) {
        mPanelInfo = info;
    }

    public void showBottomTextBox(String text, String secondText, int hideDelay) {
        if (mActivity != null) {
            final View bottomTextBox;
            ViewStub stub = (ViewStub) mActivity.findViewById(R.id.bottom_text_box_stub);
            if (stub != null) {
                bottomTextBox = stub.inflate();
            } else {
                bottomTextBox = mActivity.findViewById(R.id.bottom_text_box);
            }
            if (bottomTextBox != null) {
                View close = bottomTextBox.findViewById(R.id.close);
                if (close != null) {
                    close.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            ViEffectMgr.getInstance().showBottomTextBox(bottomTextBox, false);
                        }
                    });
                }
                TextView tv = (TextView) bottomTextBox.findViewById(R.id.text);
                if (text != null) {
                    tv.setText(text);
                }

                TextView secondTv = (TextView) bottomTextBox.findViewById(R.id.text_second);
                if (secondTv != null) {
                    secondTv.setText(getString(R.string.last_synced, secondText));
                }

                ViEffectMgr.getInstance().showBottomTextBox(bottomTextBox, true);

                if (hideDelay > 0) {
                    bottomTextBox.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            ViEffectMgr.getInstance().showBottomTextBox(bottomTextBox, false);
                        }
                    }, hideDelay);
                }
            }
        }
    }

    public long getTotalFileSize() {
        long totalFileSize = 0;
        for (int i = 0; i < getTotalFileCount(); i++) {
            FileRecord record = getFileRecord(i);
            if (record != null) {
                totalFileSize += record.getSize();
            }
        }
        return totalFileSize;
    }

    public FileListActionMenu getActionMenu() {
        return mMenu;
    }

    protected final Handler mSmartTipHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case SmartTipMgr.SHOW_SMART_TIP:
                    showSmartTipPopup();
                    break;
                case SmartTipMgr.SCROLL_UP_IN_PORTRAIT_MODE:
                    setScrollViewFullDown(SmartTipMgr.SCROLL_UP_IN_PORTRAIT_MODE);
                    break;
                case SmartTipMgr.SCROLL_UP_IN_LANDSCAPE_MODE:
                    setScrollViewFullDown(SmartTipMgr.SCROLL_UP_IN_LANDSCAPE_MODE);
                    break;
            }
        }
    };

    public void showSmartTipPopup() {
        if (mContext == null) {
            return;
        }
        int previousTipState = PreferenceUtils.getPreviousTipState(mContext);
        int previousTipType = PreferenceUtils.getPreviousTipType(mContext);

        //TODO HYL ?
        /*
        if (previousTipState != SemTipPopup.STATE_DISMISSED) {
            if (previousTipType == AppConstants.SmartTipType.GMS && !PreferenceUtils.getGmsVisitFlag(mContext)) {
                showGmsSmartTipPopup();
            } else {
                showCloudSmartTipPopup();
            }
        } else {
            if (SmartTipUtils.needGmsSmartTipPopup(mContext)) {
                showGmsSmartTipPopup();
            } else if (SmartTipUtils.needCloudSmartTipPopup(mContext, mNavigationInfo)) {
                showCloudSmartTipPopup();
            }
        }
        */
    }

    private void showGmsSmartTipPopup() {
        final int resId = getResources().getIdentifier("action_bar_container", "id", "android");
        final ViewGroup actionbarView = (ViewGroup) getActivity().getWindow().getDecorView().findViewById(resId);
        if (actionbarView != null) {
            View actionMenuView = actionbarView.getChildAt(0);
            if (UiUtils.getScreenState(mContext) == AppConstants.PORTRAIT) {
                SmartTipUtils.saveGmsPortraitLocation(mContext, actionMenuView);
            } else {
                SmartTipUtils.saveGmsLandscapeLocation(mContext, actionMenuView);
            }
            SmartTipMgr.getInstance(getActivity()).createSmartTipPopup(actionMenuView, AppConstants.SmartTipType.GMS);
        }
    }

    protected void showCloudSmartTipPopup() {
        final View itemView = mView.findViewById(R.id.cloud_storage_samsung_drive).findViewById(R.id.home_list_item_thumbnail);
        SmartTipMgr.getInstance(getActivity()).createSmartTipPopup(itemView, AppConstants.SmartTipType.CLOUD);
    }

    public void setScrollViewFullDown(int actionType) {
        if (mView != null) {
            int scrollViewId = (actionType == SmartTipMgr.SCROLL_UP_IN_PORTRAIT_MODE) ? R.id.scrollView : R.id.note_scrollView;
            ScrollView scrollView = (ScrollView) mView.findViewById(scrollViewId);
            if (scrollView != null) {
                scrollView.fullScroll(ScrollView.FOCUS_DOWN);
            }
        }
    }

    protected void checkSmartTipCondition() {
        boolean draw = !(mActivity instanceof GetMoreSpaceActivity) && !(mActivity instanceof FolderSelectorBottomSheetActivity) &&
                ((!AppFeatures.isNote()) || (UiUtils.getScreenState(mContext) == AppConstants.PORTRAIT && mView.findViewById(R.id.note_scrollView) == null));
        if (draw) {
            SmartTipMgr.getInstance(getActivity()).clearSmartTipPopup();
            if (SmartTipUtils.planToDrawCloudSmartTip(mContext)) {
                mSmartTipHandler.sendEmptyMessageDelayed(SmartTipMgr.SCROLL_UP_IN_PORTRAIT_MODE, SmartTipMgr.SCROLL_UP_DELAY_TIME);
            }
            Log.d(this, "checkSmartTipCondition() ] Smart Tip will show");
            mSmartTipHandler.removeMessages(SmartTipMgr.SHOW_SMART_TIP);
            mSmartTipHandler.sendEmptyMessageDelayed(SmartTipMgr.SHOW_SMART_TIP, SmartTipMgr.SHOW_SMART_TIP_DELAY_TIME);
        }
    }
}
